home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
NextAnswers
/
PeopleDemo_sybase
/
MainController.m
< prev
next >
Wrap
Text File
|
1994-06-24
|
7KB
|
276 lines
/* MainController.m
* You may freely copy, distribute, and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to its
* fitness for any particular use.
*
* Written by Mai Nguyen, NeXT Developer Support
*/
#import "MainController.h"
#import "Department.h"
#import "strings.h"
@implementation MainController
- init
{
[super init];
return self;
}
- appDidInit:sender
{
dbDataSource = [masterController dataSource];
dbChannel = [dbDataSource databaseChannel];
adaptorChannel = [dbChannel adaptorChannel];
rootEntity = [dbDataSource entity];
[self setDelegates];
[self fetch:sender];
return self;
}
/* Perform a fetch based on the latest options specified by user. */
- fetch:sender
{
if (optionsPanel)
[optionsPanel orderOut:sender];
[self setUpFetch:sender];
[masterController fetch];
return self;
}
- newRecord:sender
{
int i;
/* Clear all the current values in the form cells to prepare
* for the insertion of a new record.
*/
for (i = 0; i < 5; i++)
[formMatrix setStringValue:"" at:i];
return self;
}
- insert:sender
{
/* Disable the INSERT Button if the input is not valid */
if ([self validateRecord] == NO) {
[insertButton setState:0];
NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
}
else {
[insertButton setState:1];
[masterController insert:sender];
}
return self;
}
/* Set up the fetch order and specify a qualifier
* for the master table "Department"
*/
- setUpFetch:sender
{
const char *inputString;
const char *attrName = NULL;
EOQualifier *aQualifier;
id fetchOrder;
id sortAttribute;
int orderType;
/* build the qualifier.
If the input string is empty, fetch all records.
*/
inputString = [(TextField *)textField stringValue];
if (inputString == NULL)
[dbDataSource setQualifier: [rootEntity qualifier]];
else {
aQualifier = [[[EOQualifier alloc] initWithEntity:rootEntity
qualifierFormat:@"%A >= %d", @"DeptId",
[textField intValue]] autorelease];
[dbDataSource setQualifier:aQualifier];
}
/* build the fetch order based on the first column of the master
* tableview
*/
orderType = [sortMatrix selectedTag];
attrName = [[masterTableview columnAt:0] title];
sortAttribute = [rootEntity attributeNamed:[ [[NSString alloc]
initWithCString:attrName] autorelease]];
fetchOrder = [NSArray arrayWithObject:[[[EOAttributeOrdering alloc]
initWithAttribute:sortAttribute ordering: orderType] autorelease]];
[dbDataSource setFetchOrder:fetchOrder];
return self;
}
- (BOOL) validateRecord
{
int newId, newLocation;
BOOL result = YES;
newId = [formMatrix intValueAt:0];
newLocation = [formMatrix intValueAt:2];
/* Do validation here */
if ( newId < 100 || newId > 999) {
NXRunAlertPanel(NULL, ERR_INVALID_ID, NULL, NULL, NULL);
result = NO;
}
if ( newLocation != 1101 && newLocation != 1103
&& newLocation != 1104 && newLocation != 1106
&& newLocation != 1207) {
NXRunAlertPanel(NULL, ERR_INVALID_LOCATION, NULL, NULL, NULL);
result = NO;
}
return result;
}
- setDelegates
{
#ifdef DEBUG
[adaptorChannel setDebugEnabled:YES];
#endif
[adaptorChannel setDelegate:self];
[(EOController *) masterController setDelegate:self];
return self;
}
@end
@implementation MainController (EOAdaptorDelegation)
/* This method is useful to trace SQL queries */
- (void)adaptorChannel:channel
didEvaluateExpression:(NSString *)expression
{
if (sqlPanel) {
[text appendToText:"SQL Query:\n"];
[text appendToText:[expression cString]];
[text appendToText:"\n"];
}
}
@end
@implementation MainController (EOControllerDelegation)
/* This method is called before each update. Since the controller has
* buffer edits turned ON, this method is called when the user explicitly
* presses the UPDATE button.
*/
- (NSDictionary *)controller:(EOController *)controller
willSave: (NSDictionary *)edits object:object
{
if ([self validateRecord] == YES)
return edits;
else {
NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
return nil;
}
}
/* Take the input from the formcells and create a new record */
- (BOOL)controller:controller willInsertObject:object inDataSource:dataSource;
{
[object setDeptId:[NSNumber numberWithInt:[formMatrix intValueAt:0]]];
[object setDepartmentName:[[[NSString alloc] initWithCString:
[formMatrix stringValueAt:1]] autorelease]];
[object setLocationId:[NSNumber numberWithInt:
[formMatrix intValueAt:2]]];
/* The to-many relationship points to an empty autoreleased array */
[object setToEmployee:[NSArray array]];
return YES;
}
/* After insertion, refetch object so that the derived attributes are
* properly redisplayed.
*/
- (void)controller:(EOController *)controller didInsertObject:object
inDataSource:dataSource
{
[dbChannel refetchObject:object];
}
/* After an update, refetch object so that the derived attributes are
* properly redisplayed.
*/
- (void)controller:(EOController *)controller didUpdateObject:object
inDataSource:dataSource
{
[dbChannel refetchObject:object];
}
/* When the insert operation failed, remove the wrong record and rollback
* the data source. A failure usually happens when trying to insert a duplicate
* key.
*/
- (EODataSourceFailureResponse)controller:(EOController *)controller
failedToInsertObject:object
inDataSource:dataSource;
{
NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
[controller deleteObjectAtIndex:[masterTableview selectedRow]];
return EORollbackDataSourceFailureResponse;
}
/* When deleting a department, we need to null all the references
* to that department. Therefore, the "toEmployee" relationship is
* used to find the employee records attached to a given department.
* All department ids will then be nulled out.
*/
- (BOOL)controller:controller willDeleteObject:object
{
NSArray *employeeArray = [object toEmployee];
NSEnumerator *enumerator = [employeeArray objectEnumerator];
EOGenericRecord *employee;
while(employee = [enumerator nextObject]) {
[employee setObject:[EONull null] forKey:@"DeptId"];
[(id)[controller dataSource] updateObject:employee];
}
return YES;
}
/* Implementing this delegate method allows the controller to discard
* pending edits. In this example, pending edits are edits rejected by
* the validation mechanism, hence they can be discarded.
*/
- (BOOL) controllerWillDiscardEdits:(EOController *)controller
{
return YES;
}
@end
@implementation Text(printResults)
- appendToText:(const char *)newText
{
int currentLength = [self textLength];
[self setSel:currentLength :currentLength];
[self replaceSel:newText];
[self scrollSelToVisible];
return self;
}
@end